import sys
import traceback
from typing import Optional, Dict, Any
from cryptography.hazmat.primitives import serialization
from apps.deps.JWT import create_access_token
from apps.deps.RSA import rsa_decrypt
from apps.models.models import User
from apps.deps.pwdabout import pwd_verify
from datetime import timedelta


async def get_public_key(k_generator) -> str:
    """
    获取RSA公钥
    :param k_generator: 密钥生成器
    :return: PEM格式的公钥字符串
    """
    public_key = k_generator.get_public_keys()
    pem_public_key = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    ).decode("utf-8")
    return pem_public_key


async def authenticate_user(username: str, password: str, k_generator) -> Optional[Dict[str, Any]]:
    """
    验证用户登录
    :param username: 用户名
    :param password: 加密后的密码
    :param k_generator: 密钥生成器
    :return: 登录成功返回包含token等信息的字典，失败返回None
    """

    try:
        db_user = await User.get_or_none(username=username)
        if not db_user:
            return None
        decrypted_password = await rsa_decrypt(password, k_generator)
        print('---------------------')
        if await pwd_verify(decrypted_password, db_user.password):
            token = create_access_token(
                data={
                    "username": db_user.username,
                    "role": db_user.role
                },
                expires_delta=timedelta(minutes=30)
            )
            return {
                "access_token": token,
                "role": str(db_user.role.value),
                "user_id": db_user.user_id
            }
        else:
            return None
    except Exception as e:
    # 记录详细的异常信息但不重新抛出
        exc_type, exc_value, exc_traceback = sys.exc_info()
        print(f"authenticate_user函数发生异常: {exc_type.__name__}: {str(e)}")
        traceback.print_exception(exc_type, exc_value, exc_traceback)
        return None
